<template>
    <div class="chat-containers-wrapper">
        <!-- 侧边栏 -->
        <ChatSidebar ref="chatSidebarRef" :active-chat-id="conversation_id" @select="handleSelectChat"
            @new-chat="handleNewChat" />
        <!-- 主聊天区域 -->
        <div class="chat-main">
            <div class="chat-messages-wrapper">
                <!-- 消息列表 -->
                <ChatMessages :messages="messages" :current-streaming-answer-id="currentStreamingAnswerId"
                    @switch="switchMessage" @refresh="handleRefresh" ref="chatMessagesRef"
                    :is-streaming="isStreamingAnswerEnd" @edit="handleChatEdit"
                    @scroll-change="handleScrollStatusChange" />
                <!-- 空状态 -->
                <ChatEmpty v-if="messages.length === 0" />
                <!-- 停止响应按钮 -->
                <ChatStop :is-streaming="isStreamingAnswerEnd" :is-scrolled-to-bottom="isScrolledToBottom"
                    :msg-length="messages.length" @stop="handleStopStreaming" @scroll-down="handleScrollDown" />
                <!-- 建议区域 -->
                <ChatSuggested ref="chatSuggestedRef" :list="suggestedList" :is-streaming="isStreamingAnswerEnd"
                    @send="handleSuggestedClick" />
                <!-- 输入区域 -->
                <ChatInput ref="chatInputRef" @send-message="handleSendMessage" :is-streaming="isStreamingAnswerEnd" />
            </div>
        </div>
    </div>
</template>

<script setup>
import { ref, nextTick, onMounted, onBeforeUnmount } from "vue";
import ChatSidebar from "./components/ChatSidebar.vue";
import ChatMessages from "./components/ChatMessages.vue";
import ChatInput from "./components/ChatInput.vue";
import ChatEmpty from "./components/ChatEmpty.vue";
import ChatSuggested from "./components/ChatSuggested.vue";
import ChatStop from "./components/ChatStop.vue";
import { ElMessage } from "element-plus";
import { fetchChat, chatMessages, suggestedQuestions } from "@/api/chat";

import {
    getFormattedChatList,
    buildChatItemTree,
    getThreadMessages,
    getLastAnswer,
    updateTreeNodeById,
} from "./utils";

const chatInputRef = ref(null);
const conversation_id = ref("");
const switchMsgId = ref("");
const chatMessagesRef = ref(null);
const messages = ref([]);
const chatList = ref([]);
const currentStreamingAnswerId = ref("");
const autoFollowStreaming = ref(false);
const isStreamingAnswerEnd = ref(true);
const chatTreeData = ref([]);
const chatSidebarRef = ref(null);

const conversationID = computed(() => {
    if (conversation_id.value.startsWith('temp_')) {
        return '';
    } else {
        return conversation_id.value;
    }
})

// 更新消息列表
function updateMessagesList() {
    if (chatTreeData.value.length === 0) return;
    // 从树结构中提取当前线程的消息
    const tree = chatTreeData.value;
    const latestRoot = tree[tree.length - 1];
    const latestId = latestRoot?.id?.split("question-")[1];
    const msgid = switchMsgId.value || latestId;
    const msgs = getThreadMessages(tree, msgid);
    // 更新消息列表
    messages.value = msgs;
}

let rafHandle = 0;
function scheduleMessagesUpdate() {
    if (rafHandle) return;
    rafHandle = requestAnimationFrame(() => {
        rafHandle = 0;
        updateMessagesList();
    });
}

// 获取消息列表
const loadChatMessages = async () => {
    const res = await chatMessages({
        conversation_id: conversationID.value,
        limit: 90,
    });
    chatList.value = res.data;
    let formattedChat = getFormattedChatList(chatList.value);

    let tree = buildChatItemTree(formattedChat);

    chatTreeData.value = tree;
    let msgid = tree[tree.length - 1].id.split("question-")[1];
    let msgs = getThreadMessages(tree, msgid);
    messages.value = msgs;
    await nextTick();
    setTimeout(() => {
        if (chatMessagesRef.value) {
            chatMessagesRef.value.scrollToBottom(true);
        }
    }, 100);
};
// 建议问题
const suggestedList = ref([]);
const loadSuggestedQuestions = async (id) => {
    const res = await suggestedQuestions(id);
    suggestedList.value = res.data;
   handleScrollDown();
}
// 处理选择聊天
const handleSelectChat = (chat) => {
    suggestedList.value = [];
    if (!chat || typeof chat !== 'object') {
        return;
    }
    if (chat.id) {
        conversation_id.value = chat.id;
    }
    if (chat.id && !chat.id.startsWith('temp_')) {
        loadChatMessages();
    } else {
        messages.value = [];
    }
};

// 处理新建聊天
const handleNewChat = () => {
    updateMessagesList();
    messages.value = [];
    conversationID.value = '';
    switchMsgId.value = '';
    suggestedList.value = [];
    handleStopStreaming();
};
// 处理建议问题点击
const handleSuggestedClick = (item) => {
    sendQueryChat({
        content: item,
    });
};

// 切换消息
const switchMessage = async (id) => {
    if (!id) return;
    switchMsgId.value = id;
    // 如果用户手动切换到非当前流式回答，则关闭自动跟随
    if (id !== currentStreamingAnswerId.value) {
        autoFollowStreaming.value = false;
    }
    // 这里无需深拷贝，读取视图数据即可
    let msgs = getThreadMessages(chatTreeData.value, id);
    messages.value = msgs;
    await nextTick();
    handleScrollDown();
};

// 处理发送消息
const handleSendMessage = async (sendData) => {
    await handleStopStreaming();
    await sendQueryChat(sendData);
};

// 从新提问该消息
const handleRefresh = (sendData) => {
    sendQueryChat({
        content: sendData.query,
    }, sendData);
};

let currentFetch = null;
function sendQueryChat(sendData, messageRefresh = {}) {
    // 参数验证
    if (!sendData.content || typeof sendData.content !== 'string' || sendData.content.trim() === '') {
        ElMessage.error("请输入内容");
        return;
    }
    handleScrollDown();
    suggestedList.value = [];

    // 清理之前可能的未完成请求
    if (currentFetch && currentFetch.abort) {
        currentFetch.abort();
    }

    // 解析父消息ID（刷新优先 -> 当前可见线程最后答案 -> 树最后分支的末尾节点）
    let parent_message_id = messageRefresh.id ?
        messageRefresh.parent_message_id : getLastAnswer(messages.value)?.id;

    // 创建消息占位符
    const { placeholderQuestionId, placeholderAnswerId, questionItem, responseItem } = createMessagePlaceholders(parent_message_id, sendData);

    // 将问题和答案占位符插入到树结构
    try {
        insertMessageToTree(parent_message_id, questionItem, responseItem);
    } catch (error) {
        ElMessage.error("创建对话失败，请稍后重试");
        return;
    }

    // 初始化流式渲染状态
    initializeStreamingState(placeholderAnswerId);
    let files = [];
    if (sendData.files && sendData.files.length > 0) {
        sendData.files.forEach(file => {
            files.push({
                upload_file_id: file.id,
                type: file.type,
                transfer_method: 'local_file',
                url: ''
            })
        })
    }
    try {
        currentFetch = fetchChat({
            conversation_id: conversationID.value,
            files: files,
            inputs: {},
            parent_message_id: parent_message_id,
            query: sendData.content,
            response_mode: "streaming",
        },
            handleStreamEvent(placeholderQuestionId, placeholderAnswerId, questionItem, responseItem),
            handleStreamError(placeholderAnswerId, responseItem)
        );
    } catch (error) {
        handleStreamError(placeholderAnswerId, responseItem)(error);
    }
}

// 创建消息占位符
function createMessagePlaceholders(parent_message_id, sendData) {
    const placeholderQuestionId = `question-${Date.now()}`;
    const questionItem = {
        id: placeholderQuestionId,
        content: sendData.content,
        isAnswer: false,
        message_files: sendData.files,
        parentMessageId: parent_message_id,
        children: []
    };

    const placeholderAnswerId = `answer-placeholder-${Date.now()}`;
    const responseItem = {
        id: placeholderAnswerId,
        content: "",
        agent_thoughts: [],
        message_files: [],
        isAnswer: true,
        parentMessageId: questionItem.id,
        siblingIndex: 0,
        siblingCount: 1,
        children: [],
        query: sendData.content,
        answer: "",
        retriever_resources: []
    };

    return { placeholderQuestionId, placeholderAnswerId, questionItem, responseItem };
}

// 将消息插入到树结构
function insertMessageToTree(parent_message_id, questionItem, responseItem) {
    chatTreeData.value = updateTreeNodeById(
        chatTreeData.value,
        parent_message_id,
        (parentNode) => {
            if (!Array.isArray(parentNode.children)) parentNode.children = [];

            // 计算兄弟索引/数量
            const siblingIndex = parentNode.children.length;
            const siblingCount = siblingIndex + 1;

            // 设置索引信息
            responseItem.siblingIndex = siblingIndex;
            responseItem.siblingCount = siblingCount;

            // 构建父子关系
            questionItem.children.push(responseItem);
            parentNode.children.push(questionItem);
        }
    );
}

// 初始化流式渲染状态
function initializeStreamingState(placeholderAnswerId) {
    currentStreamingAnswerId.value = placeholderAnswerId;
    autoFollowStreaming.value = true;
    isStreamingAnswerEnd.value = false;

    // 切换到新分支并刷新消息列表
    if (autoFollowStreaming.value) {
        switchMsgId.value = placeholderAnswerId;
        updateMessagesList();
    }
}

// 处理流式响应事件
function handleStreamEvent(placeholderQuestionId, placeholderAnswerId, questionItem, responseItem) {
    return (event) => {
        // 避免空事件处理
        if (!event || !event.trim()) return;

        try {
            if (event.trim().startsWith("data:")) {
                const data = event.replace(/^data: ?/, "").trim();
                // 防止空数据解析错误
                if (!data) return;
                const parsed = JSON.parse(data);
                // 处理消息内容
                if (parsed.answer && parsed.event === "message") {
                    handleMessageEvent(parsed, placeholderQuestionId, placeholderAnswerId, questionItem, responseItem);
                }
                // 处理消息结束
                else if (parsed.event === "message_end") {
                    handleMessageEndEvent(parsed, responseItem);
                }
            }
        } catch (error) {
            console.error("处理流式事件失败:", error);
        }
    };
}

// 处理消息事件
function handleMessageEvent(parsed, placeholderQuestionId, placeholderAnswerId, questionItem, responseItem) {
    const messageId = parsed.id;
    const isFirstChunkWithServerId = responseItem.id === placeholderAnswerId && !!messageId;

    // 累加回答内容
    responseItem.content += parsed.answer;

    // 首次收到服务端ID时更新占位符
    if (isFirstChunkWithServerId) {
        updateMessageIds(placeholderQuestionId, placeholderAnswerId, messageId, questionItem, responseItem);
    }

    // 更新答案内容
    updateNodeContent(responseItem.id, { content: responseItem.content });
    scheduleMessagesUpdate();
}

// 更新消息ID
function updateMessageIds(placeholderQuestionId, placeholderAnswerId, messageId, questionItem, responseItem) {
    // 更新内存中的对象ID
    questionItem.id = `question-${messageId}`;
    responseItem.id = messageId;
    responseItem.parentMessageId = questionItem.id;

    // 更新树结构中的答案节点ID
    updateNodeContent(placeholderAnswerId, {
        id: messageId,
        parentMessageId: `question-${messageId}`
    });

    // 更新树结构中的问题节点ID
    updateNodeContent(placeholderQuestionId, {
        id: `question-${messageId}`
    });

    // 更新当前流式回答ID
    currentStreamingAnswerId.value = messageId;
    if (autoFollowStreaming.value) {
        switchMsgId.value = messageId;
    }
}

// 更新节点内容的工具函数
function updateNodeContent(nodeId, updates) {
    try {
        chatTreeData.value = updateTreeNodeById(
            chatTreeData.value,
            nodeId,
            (node) => {
                Object.assign(node, updates);
            }
        );
    } catch (error) {
        console.error(`更新节点内容失败 (节点ID: ${nodeId}):`, error);
    }
}

// 处理消息结束事件
function handleMessageEndEvent(parsed, responseItem) {
    // 更新最终数据
    responseItem.answer = responseItem.content;
    responseItem.retriever_resources = parsed.metadata?.retriever_resources || [];

    // 更新树结构中的最终数据
    updateNodeContent(responseItem.id, {
        content: responseItem.content,
        answer: responseItem.answer,
        retriever_resources: responseItem.retriever_resources
    });
    scheduleMessagesUpdate();
    // 加载建议问题
    loadSuggestedQuestions(parsed.message_id);
    // 清理流式状态
    cleanupStreamingState(parsed.conversation_id);
}

// 清理流式状态
function cleanupStreamingState(conversationId) {
    currentStreamingAnswerId.value = "";
    autoFollowStreaming.value = false;
    isStreamingAnswerEnd.value = true;
    // 保存会话ID
    if (conversationId) {
        try {
            window.localStorage.setItem('conversationID', conversationId);
            if (!conversationID.value && chatSidebarRef.value) {
                chatSidebarRef.value.upData();
            }
        } catch (error) {
            console.error("保存会话ID失败:", error);
        }
    }

    if (chatMessagesRef.value) {
        chatMessagesRef.value.scrollToBottom(true);
    }
}

// 处理流式错误
function handleStreamError(placeholderAnswerId, responseItem) {
    return (error) => {
        // 忽略取消请求的错误
        if (error.name === 'AbortError') {
            console.log("请求已取消");
            return;
        }

        console.error("请求错误:", error);

        // 更新错误状态
        try {
            const errorNodeId = responseItem.id || placeholderAnswerId;
            updateNodeContent(errorNodeId, {
                content: "抱歉，请求出错了，请稍后重试。",
                isError: true
            });

            updateMessagesList();
        } catch (e) {
            console.error("错误状态更新到树失败:", e);
            ElMessage.error("请求出错，无法更新界面状态");
        } finally {
            // 确保状态清理
            currentStreamingAnswerId.value = "";
            autoFollowStreaming.value = false;
        }
    };
}

const handleChatEdit = (message) => {
    chatInputRef.value.setMessageText(message.content);
};
const handleStopStreaming = () => {
    if (currentFetch) {
        currentFetch.abort();
        currentFetch = null;
    }
    cleanupStreamingState();
};

// 滚动状态变量
const isScrolledToBottom = ref(false);

// 处理滚动状态变化
const handleScrollStatusChange = (isBottom) => {
    isScrolledToBottom.value = isBottom;
};

// 处理滚动到底部
const handleScrollDown = () => {
    if (chatMessagesRef.value) {
        chatMessagesRef.value.scrollToBottom(true);
        isScrolledToBottom.value = true;
    }
};


// 组件挂载
onMounted(() => {
    // 消息列表组件的滚动逻辑已经内置，无需额外处理
});
</script>

<style lang="scss">
.chat-containers-wrapper {
    height: calc(100vh - 0px);
    display: flex;
    background: #fff;

    .max-width {
        max-width: 1000px;
        min-width: 400px;
        width: 100%;
        margin: 0 auto;
    }

    .chat-main {
        flex: 1;
        background: #fff;
        height: 100%;

        .messages-list {
            margin: 0 auto;
            max-width: 1000px;
            min-width: 400px;
        }

        .chat-messages-wrapper {
            height: 100%;
            width: 100%;
            margin: 0 auto;
            display: flex;
            flex-direction: column;
            justify-content: center;
            padding: 0 15px 15px;
            box-sizing: border-box;

        }

    }
}


// 响应式设计
@media (max-width: 768px) {
    .chat-container {
        .chat-sidebar-wrapper {
            width: 100%;
            position: absolute;
            z-index: 1000;
            transform: translateX(-100%);
            transition: transform 0.3s;

            &.show {
                transform: translateX(0);
            }
        }

        .chat-main {
            width: 100%;
            border-radius: 0;
        }
    }
}
</style>
